grammar CudaTranslator;

options {
 language=CSharp3;
 output=AST;
  ASTLabelType=CommonTree;
}

tokens {
NEGATION;
}


@lexer::namespace {cudaTranslator}
@parser::namespace{cudaTranslator}

public prog   returns [int prog]   	: 'nvidia'? (stmt|func)+ EOF^ {$prog = 0;};
 
public parm_types 	: (TYPE ID ( ',' TYPE ID )* )?;

public func      	: (TYPE ID^ '(' parm_types ')' '{'stmt* '}')
            		| (VOID ID^ '(' parm_types ')' '{'stmt* '}');
            	
public stmt      	: '{'^ ( stmt )* '}'
			| 'if'^ '('! expr ')'! stmt ( 'else' stmt )? 
            		| 'while'^ '('! expr ')'! stmt 
            		| 'for'^ '('! ID '=' INTCON ':' INTCON ')'! stmt
            		| 'return'^ ( expr )? ';'
            		|  ID ('('! (expr ( ',' expr )*)? ')'!)? assg? ';'^
            		|  TYPE^ ID ('('! expr ( ','! expr )* ')'!)? assg? (','ID ('(' expr ( ',' expr )* ')')? assg?)*';'!
            		| ';'!
            		| 'print'^ ID ('('! (expr ( ',' expr )*)? ')'!)?  ';'; 
  
public assg      	: '='^ expr;	 

public expr		:  relop (('&&'^| '^^'^| '||'^ ) relop)* ;	

public relop		:  plus ( ('=='^|'!='^|'<='^|'<'^|'>='^|'>'^) plus)*;

public plus		:  mult (('+'^|'-'^) mult)*;

public mult		:  unary (('*'^|'/'^|'/.'^|'*.'^|'mod'^) unary)* ;

public unary		:  (negation^|'+'! | '!'^)* post;
 
public post 		:  atom ('\''^)*;

public negation		:  '-' -> NEGATION;		 

public atom		:  (ID^ ( '(' (expr ( ',' expr )* )? ')')?) | INTCON | STRINGCON | matcon| matrange | FLOATCON   | ('(' expr ')') ;


public matcon		: ('['^ negation? INTCON(',' negation? INTCON)* (';' negation? INTCON(',' negation? INTCON)*)*']') | ('[' negation? FLOATCON(',' negation? FLOATCON)* (';' negation? FLOATCON(',' negation? FLOATCON)*)*']'); 
        
public matrange		: '[' negation? INTCON '->' negation? INTCON ']';

TYPE     		: 'string' | 'matrix' | 'int' | 'float';

VOID			: 'void';

ID  			: ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
    			;

INTCON 			: '0'..'9'+
    			;


FLOATCON
    			:   ('0'..'9')+ '.' ('0'..'9')* EXPONENT?
    			|   '.' ('0'..'9')+ EXPONENT?
    			|   ('0'..'9')+ EXPONENT
    			;


STRINGCON		:'"' ( ~( '\\' | '"' | '\r' | '\n' ) )* '"';

COMMENT			:   '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}
    			|   '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;}
    			;

WHITESPACE  		:   ( ' '
        		| '\t'
        		| '\r'
        		| '\n'
        		) {$channel=HIDDEN;}
    			;



EXPONENT 		: ('e'|'E') ('+'|'-')? ('0'..'9')+ ;


